package com.zdy.socketserver.sound;

import com.jacob.activeX.ActiveXComponent;
import com.jacob.com.Dispatch;
import com.jacob.com.Variant;
import org.jaudiotagger.audio.AudioFile;
import org.jaudiotagger.audio.AudioFileIO;
import org.jaudiotagger.audio.exceptions.CannotReadException;
import org.jaudiotagger.audio.exceptions.InvalidAudioFrameException;
import org.jaudiotagger.audio.exceptions.ReadOnlyFileException;
import org.jaudiotagger.tag.TagException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import sun.audio.AudioPlayer;
import sun.audio.AudioStream;

import javax.annotation.PostConstruct;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.LinkedList;
import java.util.Queue;

/**
 * @author myh
 * @date 2024/6/13
 */
@Component
public class Sound extends Thread {

    private static final Logger log = LoggerFactory.getLogger(Sound.class);

    //tts语音播报队列
    private static Queue<String> strList = new LinkedList<>();

    private static Thread tts = new Thread();
    //播放音乐
    private static AudioStream as = null;
    private static Thread t = new Thread();

    /*将播报语音添加到队列中*/
    public void call(String text) {
        ActiveXComponent activeXComponent = new ActiveXComponent("Sapi.SpVoice");
        //运行时输出语音内容
        Dispatch dispatch = activeXComponent.getObject();
        //文件名称
        long t1 = System.currentTimeMillis();
        String strName = String.valueOf(t1);
        strList.add(strName);
        try {
            //生成语音文件
            activeXComponent = new ActiveXComponent("Sapi.SpFileStream");
            Dispatch fileStreamDispatch = activeXComponent.getObject();
            //音频
            activeXComponent = new ActiveXComponent("Sapi.SpAudioFormat");
            Dispatch audioDispatch = activeXComponent.getObject();
            //设置文件流格式
            Dispatch.putRef(fileStreamDispatch, "Format", audioDispatch);
            //设置音频流格式
            Dispatch.put(audioDispatch, "Type", new Variant(22));
            //调用输出文件流打开方法，创建一个.wav .mp3 .mp4   .wma文件
            Dispatch.call(fileStreamDispatch, "Open", new Variant("D:\\sound\\" + strName + ".wav"), new Variant(3), new Variant(true));
            //设置声音对象的音频流输出流为输出文件对象
            Dispatch.putRef(dispatch, "AudioOutputStream", fileStreamDispatch);
            //设置音量0-100
            Dispatch.put(dispatch, "Volume", new Variant(100));
            //设置朗读速度
            Dispatch.put(dispatch, "Rate", new Variant(-2));
            //开始朗读
            Dispatch.call(dispatch, "Speak", new Variant(text));
            //关闭输出文件流
            Dispatch.call(fileStreamDispatch, "Close");
            Dispatch.putRef(dispatch, "AudioOutputStream", null);
            audioDispatch.safeRelease();
            fileStreamDispatch.safeRelease();
            dispatch.safeRelease();
            activeXComponent.safeRelease();
            //播放音频
            ttsPlayer(1);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 播放音频
     */
    @PostConstruct
    public void ttsPlayer() {
        //判断线程状态
        if (!tts.isAlive()) {
            tts = new Thread() {
                public void run() {
                    //是否正在播放音乐
//                    if (t.isAlive()) {
//                        ttsStop();
//                    }
                    //播放音频
                    ttsPlayer(1);
                }
            };
            tts.start();
        }


    }

    public void ttsPlayer(int playCount) {
        String folderPath = "D:\\sound";
        File folder = new File(folderPath);
        if(!folder.exists()){
            boolean mkdir = folder.mkdir();
            if(!mkdir){
                log.error("创建文件夹失败");
            }
        }
        while (!strList.isEmpty()) {
            //输出音频时长
            String fileName = strList.poll().toString();
            File file = new File("D:\\sound\\" + fileName + ".wav");
            // 使用try-with-resources自动关闭资源
            for (int i = 0; i < playCount; i++) {
                try (FileInputStream fileau = new FileInputStream(file);
                     AudioStream as = new AudioStream(fileau)) {
                    AudioFile mp3 = AudioFileIO.read(file);
                    // 开始播放
                    log.info("开始播放声音");
                    AudioPlayer.player.start(as);
                    // 精确等待音频播放完成，但需注意sleep的不精确性
                    Thread.sleep((mp3.getAudioHeader().getTrackLength() * 1000L + 500));
                    log.info("声音播放完成");
                } catch (InterruptedException | CannotReadException | IOException | TagException |
                         ReadOnlyFileException |
                         InvalidAudioFrameException e) {
                    e.printStackTrace();
                    log.error("播放音频失败"+e.getMessage());
                    Thread.currentThread().interrupt(); // 重新设置中断状态

                    throw new RuntimeException(e);
                }
            }

            //删除播放完成的音频
            boolean delete = file.delete();
            log.info(fileName+"删除文件："+ delete);
        }

    }


    /*文字转语音播报停止*/
    public void ttsStop() {
        try {
            //停止线程
            tts.interrupt();
            //停止播报
            AudioPlayer.player.stop(as);
            //清空列表所有元素
            strList.clear();

        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
